//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.1
#include "app_led.h"
#include <string.h>
#include <stdio.h>

/************************************************************内部结构Start**********************************************************************/
typedef enum
{
    LED_Lock   = 0,//上锁
    LED_Unlock = 1,//解锁
}WHT_LED_State_Lock_enum;

typedef enum
{
    LED_Mode_Routine = 0,//常灭或常亮
    LED_Mode_Flash   = 1,//闪烁
    LED_Mode_SOS     = 2,//国际SOS求救
}WHT_LED_Mode_enum;

typedef enum
{
    SOS_Short_Flash  = 0,//短闪
    SOS_Length_Flash = 1,//长闪
    SOS_Cycle_Idle   = 2,//与下次闪烁间隔
}WHT_SOS_Run_State_enum;

typedef struct
{
    WHT_LED_State_Lock_enum Lock;//上锁后LED不刷新
    WHT_LED_State_enum State;
}WHT_LED_Routine_t;//LED常规模式

typedef struct
{
    WHT_LED_State_Lock_enum Lock;    //上锁后LED不刷新
    unsigned short Flash_Count;      //闪烁次数,0表示持续闪烁
    unsigned short LED_ON_Task_Count;//点亮Count个任务时间
    unsigned short New_Task_Count;   //当前执行Count个任务时间,初始值为0
    unsigned short Cycle_Task_Count; //闪烁周期为Count个任务时间
    WHT_LED_State_enum End_State;    //结束闪烁后灯的状态
}WHT_LED_Flash_t;//LED闪烁模式

typedef struct
{
#define SOS_Flash_Count                       3                                               //SOS国际闪烁次数
#define SOS_Short_Flash_LED_ON_Task_Count     (200/(LED_Task_Update_Rate*portTICK_PERIOD_MS)) //短闪点亮时间
#define SOS_Short_Flash_Cycle_Task_Count      (400/(LED_Task_Update_Rate*portTICK_PERIOD_MS)) //短闪周期时间
#define SOS_Length_Flash_LED_ON_Task_Count    (500/(LED_Task_Update_Rate*portTICK_PERIOD_MS)) //长闪点亮时间
#define SOS_Length_Flash_Cycle_Task_Count     (1000/(LED_Task_Update_Rate*portTICK_PERIOD_MS))//长闪周期时间
#define SOS_Cycle_Idle_Task_Count             (1000/(LED_Task_Update_Rate*portTICK_PERIOD_MS))//SOS到下一个SOS间隔时间
    WHT_LED_Mode_enum Save_Current_Mode;
    WHT_SOS_Run_State_enum Run_State;
    unsigned short New_Task_Count;    //当前执行Count个任务时间,初始值为0
    unsigned short Short_Flash_Count; //闪烁次数
    unsigned short Length_Flash_Count;//闪烁次数
}WHT_LED_SOS_t;//LED国际救援模式

typedef struct
{
    WHT_LED_Mode_enum Mode;    //模式
    WHT_LED_Routine_t Routine; //常规
    WHT_LED_Flash_t Flash;     //闪烁
    WHT_LED_SOS_t SOS;         //国际救援
}WHT_LED_Former_t;
/*********************************************************内部结构End*************************************************************************/

static TaskHandle_t WHT_LED_Task_Handle = NULL;                   //任务句柄
static volatile WHT_LED_Former_t WHT_LED_RT_State[LED_Sum_Count]; //所有LED灯的实时状态
#ifdef Matrix_Lamp_Enable
    static volatile unsigned int* Matrix_Lamp_Row_State[Matrix_Lamp_Row] = {NULL};
    static volatile unsigned int* Matrix_Lamp_Col_State[Matrix_Lamp_Col] = {NULL};
    static volatile unsigned char WHT_LED_Matrix_Lamp[Matrix_Lamp_Row][Matrix_Lamp_Col];
#endif

#ifdef Independent_Lamp_Enable   //独立LED灯
    //这里为了操作GPIO更快使用位操作GPIO
    static volatile unsigned int* Independent_Lamp_State[Independent_Lamp_Count] = {NULL};
#endif


static void WHT_LED_State_Reset(void)
{
    for (unsigned int i = 0; i < LED_Sum_Count; i++) //所有灯点亮
    {
        WHT_LED_RT_State[i].Mode = LED_Mode_Routine;

        WHT_LED_RT_State[i].Routine.Lock = LED_Lock;
        WHT_LED_RT_State[i].Routine.State = LED_ON;

        WHT_LED_RT_State[i].Flash.End_State = LED_ON;
        WHT_LED_RT_State[i].Flash.Flash_Count = 0;
        WHT_LED_RT_State[i].Flash.LED_ON_Task_Count = 200 / (LED_Task_Update_Rate*portTICK_PERIOD_MS);
        WHT_LED_RT_State[i].Flash.Cycle_Task_Count = LED_1Hz / (LED_Task_Update_Rate*portTICK_PERIOD_MS);
        WHT_LED_RT_State[i].Flash.New_Task_Count = 0;
        WHT_LED_RT_State[i].Flash.Lock = LED_Lock;

        WHT_LED_RT_State[i].SOS.Save_Current_Mode = WHT_LED_RT_State[i].Mode;
        WHT_LED_RT_State[i].SOS.Run_State = SOS_Short_Flash;
        WHT_LED_RT_State[i].SOS.New_Task_Count = 0;
        WHT_LED_RT_State[i].SOS.Short_Flash_Count = SOS_Flash_Count;
        WHT_LED_RT_State[i].SOS.Length_Flash_Count = SOS_Flash_Count;
    }
#ifdef Matrix_Lamp_Enable
    memset((void*)&WHT_LED_Matrix_Lamp[0][0], LED_ON, Matrix_Lamp_Count);
#endif
}
static void WHT_LED_GPIO_Init(void)
{
#ifdef Independent_Lamp_Enable   //独立LED灯
	WHT_GPIO_BSP.WHT_Set_Clock(Independent_LED0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Independent_LED1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Independent_LED2_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Config_Bit_Output(Independent_LED0_GPIO_Port, Independent_LED0_GPIO_Pin, &Independent_Lamp_State[0]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Independent_LED1_GPIO_Port, Independent_LED1_GPIO_Pin, &Independent_Lamp_State[1]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Independent_LED2_GPIO_Port, Independent_LED2_GPIO_Pin, &Independent_Lamp_State[2]);

    *Independent_Lamp_State[0] = WHT_LED_RT_State[0].Routine.State;
    *Independent_Lamp_State[1] = WHT_LED_RT_State[1].Routine.State;
    *Independent_Lamp_State[2] = WHT_LED_RT_State[2].Routine.State;

	WHT_GPIO_BSP.WHT_Set_Mode(Independent_LED0_GPIO_Port, Independent_LED0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Independent_LED1_GPIO_Port, Independent_LED1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Independent_LED2_GPIO_Port, Independent_LED2_GPIO_Pin, Mode_Out_PP);
#endif 
#ifdef Matrix_Lamp_Enable     //矩阵LED灯
    //行配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_ROW0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_ROW1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_ROW2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_ROW3_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_ROW4_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_ROW0_GPIO_Port, Matrix_LED_ROW0_GPIO_Pin, &Matrix_Lamp_Row_State[0]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_ROW1_GPIO_Port, Matrix_LED_ROW1_GPIO_Pin, &Matrix_Lamp_Row_State[1]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_ROW2_GPIO_Port, Matrix_LED_ROW2_GPIO_Pin, &Matrix_Lamp_Row_State[2]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_ROW3_GPIO_Port, Matrix_LED_ROW3_GPIO_Pin, &Matrix_Lamp_Row_State[3]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_ROW4_GPIO_Port, Matrix_LED_ROW4_GPIO_Pin, &Matrix_Lamp_Row_State[4]);

    *Matrix_Lamp_Row_State[0] = LED_OFF;
    *Matrix_Lamp_Row_State[1] = LED_OFF;
    *Matrix_Lamp_Row_State[2] = LED_OFF;
    *Matrix_Lamp_Row_State[3] = LED_OFF;
    *Matrix_Lamp_Row_State[4] = LED_OFF;

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_ROW0_GPIO_Port, Matrix_LED_ROW0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_ROW1_GPIO_Port, Matrix_LED_ROW1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_ROW2_GPIO_Port, Matrix_LED_ROW2_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_ROW3_GPIO_Port, Matrix_LED_ROW3_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_ROW4_GPIO_Port, Matrix_LED_ROW4_GPIO_Pin, Mode_Out_PP);
    //列配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_COL0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_COL1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_COL2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_COL3_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_LED_COL4_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_COL0_GPIO_Port, Matrix_LED_COL0_GPIO_Pin, &Matrix_Lamp_Col_State[0]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_COL1_GPIO_Port, Matrix_LED_COL1_GPIO_Pin, &Matrix_Lamp_Col_State[1]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_COL2_GPIO_Port, Matrix_LED_COL2_GPIO_Pin, &Matrix_Lamp_Col_State[2]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_COL3_GPIO_Port, Matrix_LED_COL3_GPIO_Pin, &Matrix_Lamp_Col_State[3]);
	WHT_GPIO_BSP.WHT_Config_Bit_Output(Matrix_LED_COL4_GPIO_Port, Matrix_LED_COL4_GPIO_Pin, &Matrix_Lamp_Col_State[4]);

    *Matrix_Lamp_Col_State[0] = LED_OFF;
    *Matrix_Lamp_Col_State[1] = LED_OFF;
    *Matrix_Lamp_Col_State[2] = LED_OFF;
    *Matrix_Lamp_Col_State[3] = LED_OFF;
    *Matrix_Lamp_Col_State[4] = LED_OFF;

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_COL0_GPIO_Port, Matrix_LED_COL0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_COL1_GPIO_Port, Matrix_LED_COL1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_COL2_GPIO_Port, Matrix_LED_COL2_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_COL3_GPIO_Port, Matrix_LED_COL3_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_LED_COL4_GPIO_Port, Matrix_LED_COL4_GPIO_Pin, Mode_Out_PP);
#endif
    printf("WHT:LED GPIO Init OK!\r\n");
}

//矩阵LED灯
#ifdef Matrix_Lamp_Enable
static void WHT_LED_Set_Matrix_Col_Value(const unsigned char Matrix_LED_Row)
{
    static unsigned char Matrix_LED_Col;
    
    for (Matrix_LED_Col = 0; Matrix_LED_Col < Matrix_Lamp_Col; Matrix_LED_Col++)
    {
        *Matrix_Lamp_Col_State[Matrix_LED_Col] = WHT_LED_Matrix_Lamp[Matrix_LED_Row][Matrix_LED_Col];
    }
}
static void WHT_LED_Scan_Matrix_Callback(void)
{
    static unsigned char Matrix_LED_Row = 0;

    switch (Matrix_LED_Row)
    {
    case 0:
        *Matrix_Lamp_Row_State[4] = LED_OFF;
        WHT_LED_Set_Matrix_Col_Value(0);
        *Matrix_Lamp_Row_State[0] = LED_ON;
        break;
    case 1:
        *Matrix_Lamp_Row_State[0] = LED_OFF;
        WHT_LED_Set_Matrix_Col_Value(1);
        *Matrix_Lamp_Row_State[1] = LED_ON;
        break;
    case 2:
        *Matrix_Lamp_Row_State[1] = LED_OFF;
        WHT_LED_Set_Matrix_Col_Value(2);
        *Matrix_Lamp_Row_State[2] = LED_ON;
        break;
    case 3:
        *Matrix_Lamp_Row_State[2] = LED_OFF;
        WHT_LED_Set_Matrix_Col_Value(3);
        *Matrix_Lamp_Row_State[3] = LED_ON;
        break;
    case 4:
        *Matrix_Lamp_Row_State[3] = LED_OFF;
        WHT_LED_Set_Matrix_Col_Value(4);
        *Matrix_Lamp_Row_State[4] = LED_ON;
        Matrix_LED_Row = 0;
        break;
    default:
        break;
    }
}
#endif

static void WHT_LED_Set_State(WHT_LED_Name_enum led_number, WHT_LED_State_enum state)
{
#ifdef Independent_Lamp_Enable //独立灯
    if (led_number < Independent_Lamp_Count)//独立按键
    {
        *Independent_Lamp_State[led_number] = state;
        return;
    }
#endif
#ifdef Matrix_Lamp_Enable    //矩阵灯
    led_number = (WHT_LED_Name_enum)(led_number - Independent_Lamp_Count);//要移除到独立灯的位置
    WHT_LED_Matrix_Lamp[led_number/Matrix_Lamp_Col][led_number%Matrix_Lamp_Col] = state;
#endif
}
static void WHT_LED_Set_Routine_Value(const WHT_LED_Name_enum led_number, const WHT_LED_Routine_Config_t* routine_config)
{
    if (WHT_LED_RT_State[led_number].Mode == LED_Mode_SOS)
        return;
    WHT_LED_RT_State[led_number].Routine.Lock = LED_Lock;
    WHT_LED_RT_State[led_number].Routine.State = routine_config->State;
    WHT_LED_RT_State[led_number].Mode = LED_Mode_Routine;
    WHT_LED_RT_State[led_number].Routine.Lock = LED_Unlock;
}
static void WHT_LED_Set_Flash_Value(const WHT_LED_Name_enum led_number, const WHT_LED_Flash_Config_t* flash_config)
{
    if (WHT_LED_RT_State[led_number].Mode == LED_Mode_SOS)
        return;
    WHT_LED_RT_State[led_number].Flash.Lock = LED_Lock;                                               //上锁,停止LED刷新
    WHT_LED_RT_State[led_number].Flash.End_State = flash_config->End_State;                           //闪烁结束后的状态
    WHT_LED_RT_State[led_number].Flash.Flash_Count = flash_config->Flash_Count;                       //闪烁的次数
    WHT_LED_RT_State[led_number].Flash.LED_ON_Task_Count = flash_config->LED_ON_Time/(LED_Task_Update_Rate*portTICK_PERIOD_MS);//点亮任务时间数
    WHT_LED_RT_State[led_number].Flash.Cycle_Task_Count = flash_config->Flash_Cycle/(LED_Task_Update_Rate*portTICK_PERIOD_MS); //周期点亮任务时间数
    WHT_LED_RT_State[led_number].Flash.New_Task_Count = 0;                                            //重新计数
    WHT_LED_RT_State[led_number].Mode = LED_Mode_Flash;                                               //LED模式要更改的
    WHT_LED_RT_State[led_number].Flash.Lock = LED_Unlock;                                             //解锁,开始LED刷新
}
static void WHT_LED_Start_SOS_Config(const WHT_LED_Name_enum led_number)
{
    if (WHT_LED_RT_State[led_number].Mode != LED_Mode_SOS) //先判断，防止后面无法退出SOS模式
    {
        WHT_LED_RT_State[led_number].SOS.Save_Current_Mode = WHT_LED_RT_State[led_number].Mode;
        WHT_LED_RT_State[led_number].Mode = LED_Mode_SOS;
    }
}
static void WHT_LED_End_SOS_Config(const WHT_LED_Name_enum led_number)
{
    if (WHT_LED_RT_State[led_number].Mode == LED_Mode_SOS)
    {
        WHT_LED_RT_State[led_number].Mode = WHT_LED_RT_State[led_number].SOS.Save_Current_Mode;
        WHT_LED_RT_State[led_number].SOS.Run_State = SOS_Short_Flash;
        WHT_LED_RT_State[led_number].SOS.New_Task_Count = 0;
        WHT_LED_RT_State[led_number].SOS.Short_Flash_Count = SOS_Flash_Count;
        WHT_LED_RT_State[led_number].SOS.Length_Flash_Count = SOS_Flash_Count;
    }
}

/**************************************外部调用函数********************************************/
static void WHT_LED_Set_Routine(const WHT_LED_Routine_Config_t* routine_config)
{
    if (routine_config->Name == LED_ALL)
        for (unsigned int i = 0; i < LED_Sum_Count; i++)
            WHT_LED_Set_Routine_Value((WHT_LED_Name_enum)i, routine_config);
    else if (routine_config->Name < LED_Sum_Count)
        WHT_LED_Set_Routine_Value(routine_config->Name, routine_config);
    vTaskResume(WHT_LED_Task_Handle);//恢复任务
}
static void WHT_LED_Set_Flash(const WHT_LED_Flash_Config_t* flash_config)
{
    if (flash_config->Name == LED_ALL)
        for (unsigned int i = 0; i < LED_Sum_Count; i++)
            WHT_LED_Set_Flash_Value((WHT_LED_Name_enum)i, flash_config);
    else if (flash_config->Name < LED_Sum_Count)
        WHT_LED_Set_Flash_Value(flash_config->Name, flash_config);
    vTaskResume(WHT_LED_Task_Handle);//恢复任务
}
static void WHT_LED_Set_Routine_New(WHT_LED_Name_enum name, WHT_LED_State_enum state)
{
    WHT_LED_Routine_Config_t routine_config;

    routine_config.Name = name;
    routine_config.State = state;
    WHT_LED_Set_Routine(&routine_config);
}
static void WHT_LED_Set_Flash_New(WHT_LED_Name_enum name, unsigned short flash_count, unsigned short led_on_time, unsigned short flash_cycle, WHT_LED_State_enum end_state)
{
    WHT_LED_Flash_Config_t flash_config;

    flash_config.Name = name;
    flash_config.Flash_Count = flash_count;
    flash_config.LED_ON_Time = led_on_time;
    flash_config.Flash_Cycle = flash_cycle;
    flash_config.End_State = end_state;
    WHT_LED_Set_Flash(&flash_config);
}
static void WHT_LED_Start_SOS(const WHT_LED_Name_enum led_number)
{
    if (led_number == LED_ALL)
        for (unsigned int i = 0; i < LED_Sum_Count; i++)
            WHT_LED_Start_SOS_Config((WHT_LED_Name_enum)i);
    else if (led_number < LED_Sum_Count)
        WHT_LED_Start_SOS_Config(led_number);
    vTaskResume(WHT_LED_Task_Handle);//恢复任务
}
static void WHT_LED_End_SOS(const WHT_LED_Name_enum led_number)
{
    if (led_number == LED_ALL)
        for (unsigned int i = 0; i < LED_Sum_Count; i++)
            WHT_LED_End_SOS_Config((WHT_LED_Name_enum)i);
    else if (led_number < LED_Sum_Count)
        WHT_LED_End_SOS_Config(led_number);
}
/**************************************外部调用函数********************************************/


static void WHT_LED_Task(void* pvParameters)
{
    TickType_t xLastWakeTime;
    FlagStatus LED_End_Flag;
    unsigned int i;

    xLastWakeTime = xTaskGetTickCount();
    for (; ;)
    {
        LED_End_Flag = SET;
        vTaskDelayUntil(&xLastWakeTime, LED_Task_Update_Rate);//LED_Task_Update_Rate个任务时间刷新一下for循环
        for (i = 0; i < LED_Sum_Count; i++)
        {
            switch (WHT_LED_RT_State[i].Mode)
            {
            case LED_Mode_Routine:       //常亮或常灭
                if (WHT_LED_RT_State[i].Routine.Lock == LED_Unlock)    //被解锁就表示GPIO有更新
                {
                    WHT_LED_RT_State[i].Routine.Lock = LED_Lock;
                    WHT_LED_Set_State((WHT_LED_Name_enum)i, WHT_LED_RT_State[i].Routine.State);
                }
                break;
            case LED_Mode_Flash:         //闪烁
                if (WHT_LED_RT_State[i].Flash.Lock == LED_Unlock)                               //被上锁就不更新GPIO状态
                {
                    WHT_LED_RT_State[i].Flash.New_Task_Count++;
                    if (WHT_LED_RT_State[i].Flash.New_Task_Count >= WHT_LED_RT_State[i].Flash.Cycle_Task_Count)//到达闪烁周期
                    {
                        WHT_LED_RT_State[i].Flash.New_Task_Count = 0;                           //清零重新计数
                        if (WHT_LED_RT_State[i].Flash.Flash_Count == 0)                         //一直闪烁
                            WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                    //继续点亮
                        else                                                                    //非一直闪烁
                        {
                            WHT_LED_RT_State[i].Flash.Flash_Count--;                            //闪烁次数减1次
                            if (WHT_LED_RT_State[i].Flash.Flash_Count == 0)                     //闪烁次数用完
                            {
                                WHT_LED_RT_State[i].Flash.Lock = LED_Lock;                      //上锁,结束本次闪烁
                                WHT_LED_Set_State((WHT_LED_Name_enum)i, WHT_LED_RT_State[i].Flash.End_State);
                                printf("end led %d flash\r\n", i);                              //调试打印
                            }
                            else
                                WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                //继续点亮
                        }
                    }
                    else if (WHT_LED_RT_State[i].Flash.New_Task_Count == WHT_LED_RT_State[i].Flash.LED_ON_Task_Count)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_OFF);                       //熄灭LED
                    else if (WHT_LED_RT_State[i].Flash.New_Task_Count == 1)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                        //点亮LED
                    LED_End_Flag = RESET;
                }
                break;
            case LED_Mode_SOS:       //SOS求救信号
                WHT_LED_RT_State[i].SOS.New_Task_Count++;
                switch (WHT_LED_RT_State[i].SOS.Run_State)
                {
                case SOS_Short_Flash: //短闪
                    if (WHT_LED_RT_State[i].SOS.New_Task_Count >= SOS_Short_Flash_Cycle_Task_Count)//到达闪烁周期
                    {
                        WHT_LED_RT_State[i].SOS.New_Task_Count = 0;                                //清零重新计数
                        WHT_LED_RT_State[i].SOS.Short_Flash_Count--;                               //闪烁次数减1
                        if (WHT_LED_RT_State[i].SOS.Short_Flash_Count == 0)                        //闪烁次数用完
                        {
                            //WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_OFF);                    //熄灭LED
                            WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                       //熄灭LED  (野火指南者专用)正常情况下用上面的语句
                            WHT_LED_RT_State[i].SOS.Run_State = WHT_LED_RT_State[i].SOS.Length_Flash_Count == 0 ? SOS_Cycle_Idle : SOS_Length_Flash;
                        }
                        else
                            WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                       //点亮LED
                    }
                    else if (WHT_LED_RT_State[i].SOS.New_Task_Count == SOS_Short_Flash_LED_ON_Task_Count)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_OFF);                          //熄灭LED
                    else if (WHT_LED_RT_State[i].SOS.New_Task_Count == 1)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                           //点亮LED
                    break;
                case SOS_Length_Flash://长闪
                    if (WHT_LED_RT_State[i].SOS.New_Task_Count >= SOS_Length_Flash_Cycle_Task_Count)//到达闪烁周期
                    {
                        WHT_LED_RT_State[i].SOS.New_Task_Count = 0;                                 //清零重新计数
                        WHT_LED_RT_State[i].SOS.Length_Flash_Count--;
                        if (WHT_LED_RT_State[i].SOS.Length_Flash_Count == 0)                        //闪烁次数用完
                        {
                            WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_OFF);                       //熄灭LED
                            WHT_LED_RT_State[i].SOS.Short_Flash_Count = SOS_Flash_Count;
                            WHT_LED_RT_State[i].SOS.Run_State = SOS_Short_Flash;                    //进入SOS_Short_Flash
                        }
                        else
                            WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                        //点亮LED
                    }
                    else if (WHT_LED_RT_State[i].SOS.New_Task_Count == SOS_Length_Flash_LED_ON_Task_Count)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_OFF);                           //熄灭LED
                    else if (WHT_LED_RT_State[i].SOS.New_Task_Count == 1)
                        WHT_LED_Set_State((WHT_LED_Name_enum)i, LED_ON);                            //点亮LED
                    break;
                case SOS_Cycle_Idle://空闲间隔
                    if (WHT_LED_RT_State[i].SOS.New_Task_Count >= SOS_Cycle_Idle_Task_Count)        //到达空闲周期
                    {
                        WHT_LED_RT_State[i].SOS.New_Task_Count = 0;                                 //清零重新计数
                        WHT_LED_RT_State[i].SOS.Short_Flash_Count = SOS_Flash_Count;                //复位短闪次数
                        WHT_LED_RT_State[i].SOS.Length_Flash_Count = SOS_Flash_Count;               //复位长闪次数
                        WHT_LED_RT_State[i].SOS.Run_State = SOS_Short_Flash;                        //进入SOS_Short_Flash
                    }
                    break;
                }
                LED_End_Flag = RESET;
                break;
            }
        }
        if (LED_End_Flag == SET)
        {
            printf("WHT_LED_Task Suspend\r\n");
            vTaskSuspend(WHT_LED_Task_Handle);
        }
    }
}


static void WHT_LED_Install(unsigned char task_priority)
{
    BaseType_t xreturn;

    WHT_LED_State_Reset();
    WHT_LED_GPIO_Init();

    xreturn = xTaskCreate( WHT_LED_Task, "WHT_LED_Task", 256, NULL, task_priority, &WHT_LED_Task_Handle);
    if (xreturn == pdPASS)
        printf("WHT:LED Task Create OK!\r\n");
    else
        printf("WHT:LED Task Create Error!\r\n");
}

static void WHT_LED_Uninstall(void)
{
    vTaskDelete(WHT_LED_Task_Handle);
    printf("WHT:LED Task Delete OK!\r\n");
}

//LED的控制句柄
WHT_LED_t WHT_LED_Handle = 
{
    .LED_Task_Install    = WHT_LED_Install,
    .LED_Task_Uninstall  = WHT_LED_Uninstall,
    .LED_Set_Routine_New = WHT_LED_Set_Routine_New,
    .LED_Set_Flash_New   = WHT_LED_Set_Flash_New,
    .LED_Routine_Config  = WHT_LED_Set_Routine,
    .LED_Flash_Config    = WHT_LED_Set_Flash,
    .LED_SOS_Start       = WHT_LED_Start_SOS,
    .LED_SOS_End         = WHT_LED_End_SOS,
};
